package gemini.castor.ui.client.page.content.account.accountinfo.form;

import gemini.basic.model.Address;
import gemini.basic.model.MonthlyPoint;
import gemini.basic.model.Person;
import gemini.castor.ui.client.ServiceCatalog;
import gemini.castor.ui.client.mvp.callback.AbstractAsyncCallback;
import gemini.castor.ui.client.mvp.single.CastorWidgetDisplay;
import gemini.castor.ui.client.mvp.single.CastorWidgetPresenter;
import gemini.castor.ui.client.page.RootEvent;
import gemini.castor.ui.client.utils.GuiUtils;
import gemini.castor.ui.client.utils.PlaceConstants;

import java.util.Date;

import ch.elca.gwt.mvp.client.EventBus;
import ch.elca.gwt.mvp.client.place.Place;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.inject.Inject;

public class AccountInfoFormPresenter extends
		CastorWidgetPresenter<AccountInfoFormPresenter.Display> {

	@Inject
	public AccountInfoFormPresenter(Display display, EventBus globalEventBus) {
		super(display, globalEventBus);
	}
	
	private AccountInfoFormModel accountModel;

	public interface Display extends CastorWidgetDisplay {
		void setModel(AccountInfoFormModel createModelFromPerson);

		HasClickHandlers getChangePhoneClickHandlers();

		HasClickHandlers getChangePasswordClickHandlers();

		HasClickHandlers getChangeAddressClickHandlers();

		HasClickHandlers getChangeEmailClickHandlers();

		String getNewPhone();

		String getUsername();

		String getNewPassword();

		Address getNewAddress();

		String getNewEmail();

		boolean phoneValidate();

		boolean emailValidate();

		boolean passwordValidate();

		boolean addressValidate();

		String getConfirmPassword();

		String getConfirmAddressPassword();

		String getConfirmEmailPassword();

		String getConfirmPhonePassword();

		String getStringPasswordNotMath();

		String getStringEmailChanged();

		String getStringPhoneChanged();

		String getStringAddressChanged();

		String getStringPasswordChanged();

	}

	public static final Place PLACE = new Place(
			PlaceConstants.PLACE_ACCOUNT_INFO);

	private int personId;

	@Override
	public void setInputObject(Object ob) {
		personId = (Integer) ob;
	}

	@Override
	protected void onBind() {
		registerHandlerRegister();
		eventBus.fireEvent(new RootEvent(
				RootEvent.ForwardType.MASK));
		ServiceCatalog.getAccountService().getById(personId,
				new AbstractAsyncCallback<Person>() {

					@Override
					public void onSuccess(Person result) {
						eventBus.fireEvent(new RootEvent(
								RootEvent.ForwardType.UN_MASK));
						if (result != null) {
							accountModel= createModelFromPerson(result);
							display.setModel(accountModel);
							display.loadData();
						} else {
							GuiUtils.alert("Cannot find any persons in database!");
						}
					}
				});
	}

	private void registerHandlerRegister() {
		registerHandler(display.getChangeAddressClickHandlers()
				.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						// Change address
						if (display.addressValidate()) {
							changeAddress();
						}
					}
				}));
		registerHandler(display.getChangeEmailClickHandlers().addClickHandler(
				new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						// Change Email
						if (display.emailValidate()) {
							changeEmail();
						}
					}
				}));

		registerHandler(display.getChangePasswordClickHandlers()
				.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						// Change password
						if (display.passwordValidate()) {
							changePassword();
						}
					}
				}));

		registerHandler(display.getChangePhoneClickHandlers().addClickHandler(
				new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						// Change phone
						if (display.phoneValidate()) {
							changePhone();
						}
					}
				}));
	}

	private void changePhone() {
		ServiceCatalog.getUserService().savePhone(display.getUsername(),display.getConfirmPhonePassword(),
				display.getNewPhone(), new AbstractAsyncCallback<Boolean>() {
					@Override
					public void onSuccess(Boolean result) {
						eventBus.fireEvent(new RootEvent(
								RootEvent.ForwardType.UN_MASK));
						if (result) {
							accountModel.setPhone(display.getNewPhone());
							display.setModel(accountModel);
							display.loadData();
							GuiUtils.info(display.getStringPhoneChanged());
							
						} else {
							GuiUtils.alert(display.getStringPasswordNotMath());
						}
					}
				});
	}

	private void changePassword() {
		ServiceCatalog.getUserService().savePassword(display.getUsername(),display.getConfirmPassword(),
				display.getNewPassword(), new AbstractAsyncCallback<Boolean>() {

					@Override
					public void onSuccess(Boolean result) {
						eventBus.fireEvent(new RootEvent(
								RootEvent.ForwardType.UN_MASK));
						if (result) {
							display.loadData();
							GuiUtils.info(display.getStringPasswordChanged());
						} else {
							GuiUtils.alert(display.getStringPasswordNotMath());
						}
					}
				});
	}

	private void changeAddress() {
		ServiceCatalog.getUserService().saveAddress(display.getUsername(),display.getConfirmAddressPassword(),
				display.getNewAddress(), new AbstractAsyncCallback<Boolean>() {

					@Override
					public void onSuccess(Boolean result) {
						eventBus.fireEvent(new RootEvent(
								RootEvent.ForwardType.UN_MASK));
						if (result) {
							accountModel.setAddress(addressToString(display.getNewAddress()));
							display.setModel(accountModel);
							display.loadData();
							GuiUtils.info(display.getStringAddressChanged());
						} else {
							GuiUtils.alert(display.getStringPasswordNotMath());
						}

					}
				});
	}
	
	private String addressToString(Address add){
		String addressString = add.getAddressLine1()+", "+add.getAddressLine2()+", "+ add.getDistrict() +", "+ add.getCity() +", "+add.getCountry();
		return addressString;
		
	}

	private void changeEmail() {
		ServiceCatalog.getUserService().saveEmail(display.getUsername(),display.getConfirmEmailPassword(),
				display.getNewEmail(), new AbstractAsyncCallback<Boolean>() {

					@Override
					public void onSuccess(Boolean result) {
						eventBus.fireEvent(new RootEvent(
								RootEvent.ForwardType.UN_MASK));
						if (result) {
							accountModel.setEmail(display.getNewEmail());
							display.setModel(accountModel);
							display.loadData();
							GuiUtils.info(display.getStringEmailChanged());
						} else {
							GuiUtils.alert(display.getStringPasswordNotMath());
						}
					}
				});
	}

	@SuppressWarnings("deprecation")
	protected AccountInfoFormModel createModelFromPerson(Person person) {
		AccountInfoFormModel accountModel = new AccountInfoFormModel();
		accountModel.setId(person.getDistributor().getCode());
		accountModel.setFullname(person.getFirstName() + " "
				+ person.getLastName());
		accountModel.setIdcard(person.getIdentityCard().getNumber());
		accountModel.setAddress(person.getAddress().getAddressLine1() + ", "
				+ person.getAddress().getAddressLine2() + ", "
				+ person.getAddress().getDistrict() + ", "
				+ person.getAddress().getCity() + ", "
				+ person.getAddress().getCountry());
		accountModel.setContactAdd(person.getAddress().getAddressLine1() + ", "
				+ person.getAddress().getAddressLine2() + ", "
				+ person.getAddress().getDistrict() + ", "
				+ person.getAddress().getCity() + ", "
				+ person.getAddress().getCountry());
		accountModel.setBirthday(GuiUtils.format(person.getDateOfBirth()));
		accountModel.setEmail(person.getEmail());
		accountModel.setPhone(person.getPhoneNumber());
		accountModel.setUsername(person.getUsers().get(0).getUsername());
		accountModel.setPassword(person.getUsers().get(0).getPassword());
		accountModel.setSex(person.getSex());
		accountModel.setLanguage(person.getLanguageCode());
		accountModel.setDateOfIssue(GuiUtils.format(person
				.getIdentityCard().getDateOfIssue()));
		accountModel
				.setPlaceOfIssue(person.getIdentityCard().getPlaceOfIssue());

		Date date = new Date();
		
		int personalPoint = 0;
		int groupPoint = 0;
		
		for (MonthlyPoint mp : person.getDistributor().getMonthlyPoints()) {
			if(mp.getMonth().getMonth() == date.getMonth() + 1 && mp.getMonth().getYear() == date.getYear() + 1900){
				personalPoint = mp.getPersonalPoint();
				groupPoint = mp.getGroupPoint();
				break;
			}
		}
		
		accountModel.setPersonalPoint(personalPoint);
		accountModel.setGroupPoint(groupPoint);
		
		if (person.getPerson() == null) {
			accountModel.setMarital(false);
		} else {
			accountModel.setMarital(true);
			accountModel.setHoneyFullname(person.getPerson().getFirstName()
					+ " " + person.getPerson().getLastName());
			accountModel.setHoneyBirthday(GuiUtils.format(person
					.getPerson().getDateOfBirth()));
			accountModel.setHoneyId(String.valueOf(person.getIdentityCard()));
			accountModel.setHoneyDateOfIssue(GuiUtils.format(person
					.getPerson().getIdentityCard().getDateOfIssue()));
			accountModel.setHoneyPlaceOfIssue(person.getPerson()
					.getIdentityCard().getPlaceOfIssue());
		}

		return accountModel;
	}

	@Override
	public Place getPlace() {
		return PLACE;
	}

}
